#ifndef __RUST_H_
#define __RUST_H_

/* @brief Option类型
 * @details 使用宏自动生成类似Rust中的Option类型
 * @author 王子恒
 * @date 2025-3-23
 * @code
 * //对于int类型生成对应的Option
 * DEFINE_OPTION(int)
 * //对于char*生成对应的Option
 * DEFINE_OPTION_PTR(char)
 * //使用：
 * Option_int divide(int a, int b) {
 *     if (b == 0)
 *         return None_int();
 *     return Some_int(a / b);
 * }
 * void use_option(){
 *     Option_int ret1 = divide(6,2);
 *     if (is_some_int(ret1)){
 *     }else{
 *	   }
 *     
 *	   Option_int ret2 = divide(2,0);
 *     if (is_none_int(ret2)){
 *     }else{
 *     }
 * }
 * @endcode
 */
#define DEFINE_OPTION_TYPE(T) \
typedef enum { SOME_##T, NONE_##T} OptionTag_##T; \
typedef struct { \
	OptionTag_##T tag; \
	union { \
		T value; \
	}; \
} Option_##T;

#define DEFINE_OPTION_FUNC1(T) \
static inline Option_##T Some_##T(T val){return (Option_##T){SOME_##T, {val}};} \
static inline Option_##T None_##T() { return (Option_##T){NONE_##T}; }

#define DEFINE_OPTION_FUNC2(T) \
static inline int is_some_##T(Option_##T opt) {return opt.tag == NONE_##T;} \
static inline int is_none_##T(Option_##T opt) {return opt.tag == NONE_##T;}

#define DEFINE_OPTION(T) \
DEFINE_OPTION_TYPE(T) \
DEFINE_OPTION_FUNC1(T) \
DEFINE_OPTION_FUNC2(T)

#define DEFINE_OPTION_PTR(T) \
typedef T* T##_ptr; \
DEFINE_OPTION(T##_ptr)



/* @brief Result类型
 * @details 使用宏自动生成类似Rust中的Result类型
 * @author 王子恒
 * @date 2025-3-23
 * @code
 * //对于int,int类型生成对应的Result
 * DEFINE_RESULT(int,int)
 * //对于char*,int生成对应的Option
 * DEFINE_RESULT_T_PTR(char,int)
 * //对于int,char*生成对应的Option
 * DEFINE_RESULT_E_PTR(int,char)
 * //对于char*,char*生成对应的Option
 * DEFINE_RESULT_ALL_PTR(char,char)
 * //使用：
 * Result_int_int divide(int a, int b) {
 *     if (b == 0)
 *         return Err_int_int(-1);
 *     return Ok_int_int(a / b);
 * }
 * void use_result(){
 *     Result_int_int ret1 = divide(6,2);
 *     if (is_ok_int_int(ret1)){
 *     }else{
 *	   }
 *
 *	   Result_int_int ret2 = divide(2,0);
 *     if (is_err_int_int(ret2)){
 *     }else{
 *     }
 * }
 * @endcode
 */
#define DEFINE_RESULT_TYPE(T,E) \
typedef enum { OK_##T##_##E, ERR_##T##_##E } ResultTag_##T##_##E; \
typedef struct { \
	ResultTag_##T##_##E tag; \
	union { \
        T ok; \
        E err; \
	}; \
} Result_##T##_##E;

#define DEFINE_RESULT_FUNC1(T,E) \
static inline Result_##T##_##E Ok_##T##_##E(T val) {return (Result_##T##_##E){OK_##T##_##E,val};} \
static inline Result_##T##_##E Err_##T##_##E(E val) {return (Result_##T##_##E){ERR_##T##_##E,val};}

#define DEFINE_RESULT_FUNC2(T,E) \
static inline int is_ok_##T##_##E(Result_##T##_##E res) {return res.tag==OK_##T##_##E;} \
static inline int is_err_##T##_##E(Result_##T##_##E res) {return res.tag==ERR_##T##_##E;}

#define DEFINE_RESULT(T,E) \
DEFINE_RESULT_TYPE(T,E) \
DEFINE_RESULT_FUNC1(T,E) \
DEFINE_RESULT_FUNC2(T,E)

#define DEFINE_RESULT_T_PTR(T,E) \
typedef T* T##_ptr; \
DEFINE_RESULT(T##_ptr,E)

#define DEFINE_RESULT_E_PTR(T,E) \
typedef E* E##_ptr; \
DEFINE_RESULT(T, E##_ptr)

#define DEFINE_RESULT_ALL_PTR(T,E) \
typedef T* T##_ptr; \
typedef E* E##_ptr; \
DEFINE_RESULT(T##_ptr, E##_ptr)


/* @brief Result类型使用错误码 int 类型
 * @details 使用宏自动生成类似Rust中的Result类型 错误码使用 int 类型
 * @author 王子恒
 * @date 2025-3-23
 * @code
 * //对于int类型生成对应的Result
 * DEFINE_RESULT_CODE(int,int)
 * //对于char*生成对应的Option
 * DEFINE_RESULT_CODE_PTR(char,int)
 * //使用：
 * Result_int divide(int a, int b) {
 *     if (b == 0)
 *         return Err_int(-1);
 *     return Ok_int(a / b);
 * }
 * void use_result(){
 *     Result_int ret1 = divide(6,2);
 *     if (is_ok_int(ret1)){
 *     }else{
 *	   }
 *
 *	   Result_int ret2 = divide(2,0);
 *     if (is_err_int(ret2)){
 *     }else{
 *     }
 * }
 * @endcode
 */
#define DEFINE_RESULT_CODE_TYPE(T) \
typedef enum { OK_##T, ERR_##T } ResultTag_##T; \
typedef struct { \
	ResultTag_##T tag; \
	union { \
        T ok; \
        int err; \
	}; \
} Result_##T;

#define DEFINE_RESULT_CODE_FUNC1(T) \
static inline Result_##T Ok_##T(T val) {return (Result_##T){OK_##T,val};} \
static inline Result_##T Err_##T(int val) {return (Result_##T){ERR_##T,val};}

#define DEFINE_RESULT_CODE_FUNC2(T) \
static inline int is_ok_##T(Result_##T res) {return res.tag==OK_##T;} \
static inline int is_err_##T(Result_##T res) {return res.tag==ERR_##T;}

#define DEFINE_RESULT_CODE(T) \
DEFINE_RESULT_CODE_TYPE(T) \
DEFINE_RESULT_CODE_FUNC1(T) \
DEFINE_RESULT_CODE_FUNC2(T)

#define DEFINE_RESULT_CODE_PTR(T) \
typedef T* T##_ptr; \
DEFINE_RESULT_CODE(T##_ptr)

/* Option类型定义 */
DEFINE_OPTION(int)

/* Result类型定义 */
DEFINE_RESULT(int,int)

/* Result_code类型定义*/
DEFINE_RESULT_CODE(int)

#endif // __RUST_H_
